﻿using System;
using System.Collections.Generic;
using System.Linq;
using IGM.DataProvider;
using IGM.Framework.Constants;

namespace IGM.Business
{
    public partial class Business
    {
        #region -- Get Student Mark--

        /// <summary>
        /// This function shows list of Student Mark.
        /// </summary>
        /// <returns></returns>
        public List<StudentMark> GetListStudentMarkByKindMarkId(int kindmarkId)
        {
            return DataContex != null && kindmarkId > 0
                        ? DataContex.StudentMarks.Where(m => m.IdKindMark == kindmarkId).ToList() : new List<StudentMark>();
        }

        public List<StudentMark> GetStudentQualityIntern(int majorId, int kindmarkId, int condition)
        {
            var query = (DataContex.Students.Where(m => m.IdMajor == majorId).Select(orders => orders));

            var query1 = (DataContex.StudentMarks.Where(m => m.IdKindMark == kindmarkId && m.Mark > condition).Select(
                orders => orders));

            var matches = (query.SelectMany(a => query1, (a, b) => new { a, b }).Where(@t => @t.a.Id == @t.b.IdStudent).
                Select(@t => @t.b));

            // Order by mark
            var sortedStudents = matches.OrderByDescending(studentmark => studentmark.Mark);

            return sortedStudents.ToList();

        }

        #endregion

        #region Common

        private static bool StudentMarkCommonValidator(StudentMark studentmark, out string message)
        {
            if (string.IsNullOrWhiteSpace(studentmark.Mark.ToString()))
            {
                message = string.Format(ConstantMessages.RequireFieldIsBlank, "Điểm");
                return false;
            }

            if (studentmark.Mark < 0)
            {
                message = string.Format(ConstantMessages.DataUnderMinValue, "Điểm");
                return false;
            }

            message = string.Empty;
            return true;
        }

        #endregion

        #region -- Add Student Mark--

        /// <summary>
        /// 
        /// </summary>
        /// <param name="studentmark"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool AddStudentMarkValidator(StudentMark studentmark, out string message)
        {
            if (!StudentMarkCommonValidator(studentmark, out message)) return false;

            if (DataContex.StudentMarks.Any(s => s.IdStudent == studentmark.IdStudent && s.IdKindMark == studentmark.IdKindMark))
            {
                message = string.Format(ConstantMessages.ItemIsExisted, "Điểm số này");
                return false;
            }

            return true;
        }

        /// <summary>
        /// This function add a new facutly into list.
        /// </summary>
        public void AddStudentMark(StudentMark studentmark)
        {
            DataContex.StudentMarks.AddObject(studentmark);
            DataContex.SaveChanges();
        }

        #endregion

        #region -- Edit Student Mark --


        public bool EditStudentMarkValidator(StudentMark studentmark, out string message)
        {
            var id = studentmark.Id;

            if (!StudentMarkCommonValidator(studentmark, out message)) return false;

            if (DataContex.StudentMarks.Any(m => m.IdStudent == studentmark.IdStudent && m.IdKindMark == studentmark.IdKindMark && m.Mark == studentmark.Mark && m.Id != id))
            {
                message = string.Format(ConstantMessages.ItemIsExisted, "Điểm số này");
                return false;
            }

            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="studentmark"></param>
        /// <returns></returns>
        public bool EditStudentMark(StudentMark studentmark)
        {
            var id = studentmark.Id;
            var updateStudentMark = DataContex.StudentMarks.SingleOrDefault(f => f.Id == id);

            if (updateStudentMark == null)
                return false;

            updateStudentMark.Mark = studentmark.Mark;
            updateStudentMark.IsDebt = studentmark.IsDebt;

            DataContex.SaveChanges();
            return true;
        }

        #endregion

        #region -- Delete Student Mark--

        public bool DeleteStudentMarksValidator(IEnumerable<StudentMark> studentmarks, out string message)
        {
            const string intialize = "Điểm số: ";
            var itemsCannotIdentify = (from studentmark in studentmarks
                                       let id = studentmark.Id
                                       where !DataContex.StudentMarks.Any(m => m.Id == id)
                                       select studentmark).Aggregate(intialize, (current, studentmark) => current + (studentmark.IdStudent + ", "));

            if (itemsCannotIdentify != intialize)
            {
                message = string.Format(ConstantMessages.SomeItemsCanNotIdentify, itemsCannotIdentify.TrimEnd(','));
                return false;
            }

            message = string.Empty;
            return true;
        }

        /// <summary>
        /// Delete object
        /// </summary>
        public void DeleteStudentMarks(List<StudentMark> studentmarks)
        {
            for (var i = studentmarks.Count - 1; i >= 0; i--)
            {
                var id = studentmarks[i].Id;
                var deleteStudentMark = DataContex.StudentMarks.Single(m => m.Id == id);
                DataContex.StudentMarks.DeleteObject(deleteStudentMark);
            }
            DataContex.SaveChanges();
        }

        #endregion

        #region -- Sort Mark --

        public List<StudentMark> SortStudentMark(int kindmarkId)
        {
            IEnumerable<StudentMark> studentmarks = DataContex.StudentMarks.Where(m => m.IdKindMark == kindmarkId);
            IEnumerable<StudentMark> sortedStudents =
            from studentmark in studentmarks
            orderby studentmark.Mark descending, studentmark.StudentCode ascending
            select studentmark;

            return sortedStudents.ToList();
        }

        #endregion

        public void AddOrEditStudentAndMark(Student student, StudentMark studentmark, bool isUpdate)
        {
            var existStudent = DataContex.Students.FirstOrDefault(s => s.Code == student.Code);

            if (existStudent == null)
            {
                //Add new student and mark
                AddStudent(student);
                var addStudent = DataContex.Students.FirstOrDefault(s => s.Code == student.Code);
                studentmark.IdStudent = addStudent.Id;
                AddStudentMark(studentmark);
            }
            else if (isUpdate)
            {
                // Edit student and mark
                existStudent.DateOfBirth = student.DateOfBirth;
                existStudent.Name = student.Name;
                existStudent.IdMajor = student.IdMajor;
                existStudent.Term = student.Term;

                var existMark =
                    DataContex.StudentMarks.FirstOrDefault(
                        sm => sm.IdStudent == existStudent.Id && sm.IdKindMark == studentmark.IdKindMark);

                if (existMark != null)
                {
                    existMark.Mark = studentmark.Mark;
                    existMark.IsDebt = false;
                }
            }

        }
    }
}